/**
 * 报销单管理模块
 */

const router = require("koa-router")();
const Rb = require("./../models/rbSchema");
const UploadRecord = require("./../models/uploadRdSchema");
const Review = require("./../models/reviewSchema");
const Archive = require("./../models/rbArchiveSchema");
const util = require("./../utils/util");

router.prefix("/rb");

// 报销单列表
router.get("/list", async (ctx) => {
  // 解构前端传递的查询参数
  const { rbId, state, fraud, upload_id } = ctx.request.query;
  // 解构分页参数
  const { page, skipIndex } = util.pager(ctx.request.query);
  // 定义查询条件
  let params = {};
  // 如果有传递参数，则添加到查询条件中
  if (rbId) params.rbId = rbId;
  if (state && state != "3") params.state = state;
  if (fraud && fraud != "2") params.fraud = fraud;
  if (upload_id) params.upload_id = upload_id;
  try {
    // 根据条件查询所有用户列表
    const query = Rb.find(params, { _id: 0 });
    // 将查询到的结果进行分页处理
    const list = await query.skip(skipIndex).limit(page.pageSize);

    // 统计符合条件的总记录数
    const total = await Rb.countDocuments(params);

    ctx.body = util.success({
      page: {
        ...page,
        total,
      },
      list,
    });
  } catch (error) {
    ctx.body = util.fail(`查询异常:${error.stack}`);
  }
});

// 报销单加入审查
router.post("/addReview", async (ctx) => {
  // 待审查的报销单id数组
  const { rbId } = ctx.request.body;
  console.log(rbId);
  // 修改当前审查状态
  try {
    // 获取审查报销单信息
    const updateData = {
      state: 1,
    };

    const res_updata = await Rb.findOneAndUpdate(
      { rbId },
      updateData,
      { new: true } // 返回更新后的文档
    );

    if (!res_updata) {
      ctx.body = util.fail("加入审查失败", util.CODE.BUSINESS_ERROR);
      return;
    }

    const { upload_id, fraud, score, level } = await Rb.findOne(
      { rbId },
      "upload_id fraud score level"
    );

    // 创建新的审查对象
    const review = new Review({
      rbId: rbId,
      upload_id: upload_id,
      fraud: fraud,
      score: score,
      level: level,
    });
    await review.save();
    ctx.body = util.success("", "加入审查成功");
  } catch (error) {
    ctx.body = util.fail(error.stack, "加入审查失败");
  }
});

// 归档
router.post("/archive", async (ctx) => {
  // 接收到的归档数据
  const { rbId, upload_id, fraud, MBR_NO, POHO_NO, APP_AMT } = ctx.request.body;

  console.log(APP_AMT, rbId, upload_id);
  console.log(ctx.request.body);

  // 新增一条归档
  try {
    const archive = new Archive({
      rbId: rbId,
      upload_id: upload_id,
      fraud: fraud,
      MBR_NO: MBR_NO,
      POHO_NO: POHO_NO,
      APP_AMT: APP_AMT,
    });
    archive.save();

    // 在归档的同时会删除原有的报销单记录
    const res_rb_delete = await Rb.findOneAndDelete({ rbId });
    console.log(res_rb_delete);

    ctx.body = util.success("", "归档成功");
  } catch (error) {
    ctx.body = util.fail(error.stack, "归档失败");
  }
});

// 报销单删除/批量删除
router.post("/delete", async (ctx) => {
  // 待删除的报销单id数组
  const { rbIds } = ctx.request.body;
  // 根据条件删除报销单
  const res_Rb = await Rb.deleteMany({ rbId: { $in: rbIds } });
  const res_Review = await Review.deleteMany({ rbId: { $in: rbIds } });
  // 如果删除成功，则返回成功信息
  if (res_Rb.deletedCount > 0) {
    ctx.body = util.success(res_Rb, `共删除成功${res_Rb.deletedCount}条数据`);
  } else {
    ctx.body = util.fail("删除失败");
  }
});

// 报销单新增/编辑(此功能暂时移除)
router.post("/operate", async (ctx) => {
  // 解构前端传递的参数，取出需要的参数
  const { rbId, state, fraud, action } = ctx.request.body;
  // 如果是新增，则需要必须包含用户名称、邮箱、部门id
  if (action == "add") {
    if (!rbId) {
      ctx.body = util.fail("参数错误", util.CODE.PARAM_ERROR);
      return;
    }
    // $or表示或的关系，$and表示与的关系
    const res = await Rb.findOne({ rbId }, "_id rbId");
    if (res) {
      ctx.body = util.fail("该报销单ID已存在", util.CODE.PARAM_ERROR);
      return;
    } else {
      // 如果不存在，则进行新增操作
      try {
        // 创建新的报销单对象
        const rb = new Rb({
          rbId,
          state: state || 0, // 默认未审核
          fraud: fraud || 0, // 默认非诈骗
          createTime: new Date(),
          updateTime: new Date(),
        });
        rb.save();
        ctx.body = util.success("", "报销单新增成功");
      } catch (error) {
        ctx.body = util.fail(error.stack, "报销单新增失败");
      }
    }
  } else {
    // 如果是编辑，则需要判断有无部门id
    if (!rbId) {
      ctx.body = util.fail("报销单ID不能为空", util.CODE.PARAM_ERROR);
      return;
    }
    try {
      // 更新报销单信息
      const updateData = {
        state,
        fraud,
        updateTime: new Date(),
      };

      const res = await Rb.findOneAndUpdate(
        { rbId },
        updateData,
        { new: true } // 返回更新后的文档
      );

      if (!res) {
        ctx.body = util.fail("未找到该报销单", util.CODE.BUSINESS_ERROR);
        return;
      }

      ctx.body = util.success(res, "报销单更新成功");
    } catch (error) {
      ctx.body = util.fail(error.stack, "更新失败");
    }
  }
});

// 获取报销单上月总数量和本月总数量，即上月末数据库中的报销单数量和此时数据库中的报销单数量
router.get("/count", async (ctx) => {
  try {
    const now = new Date();
    const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);

    // 获取上个月的报销单数量
    const lastMonthCount = await Rb.countDocuments({
      createTime: {
        $gte: lastMonth,
        $lt: new Date(now.getFullYear(), now.getMonth(), 1),
      },
    });
    // 获取本月的报销单数量
    const thisMonthCount = await Rb.countDocuments();
    ctx.body = util.success(
      {
        lastMonthCount,
        thisMonthCount,
      },
      "获取报销单数量成功"
    );
  } catch (error) {
    ctx.body = util.fail(error.stack, "获取报销单数量失败");
  }
});

// 获取报销单中属性值为诈骗的数量
router.get("/fraudCount", async (ctx) => {
  try {
    // 获取属性值为诈骗的报销单数量
    const fraudCount = await Rb.countDocuments({ fraud: 1 });
    ctx.body = util.success(
      {
        fraudCount,
      },
      "获取报销单诈骗数量成功"
    );
  } catch (error) {
    ctx.body = util.fail(error.stack, "获取报销单诈骗数量失败");
  }
});

// 获取属于最近五次上传的报销单的诈骗与非诈骗数量
router.get("/recentFraudCount", async (ctx) => {
  try {
    // 1. 获取最近五次上传记录的ID
    const recentUploads = await UploadRecord.find({}, { upload_id: 1, _id: 0 })
      .sort({ upload_time: -1 })
      .limit(5);
    // 取出查询到的id，设置成数组
    const uploadIds = recentUploads.map((record) => record.upload_id);

    // 2. 如果没有上传记录，直接返回0
    if (uploadIds.length === 0) {
      return (ctx.body = util.success(
        {
          fraudCount: 0,
          normalCount: 0,
        },
        "获取统计数据成功"
      ));
    }

    // 3. 使用聚合管道统计诈骗和非诈骗数量
    const pipeline = [
      // 筛选属于最近五次上传的报销单
      { $match: { upload_id: { $in: uploadIds } } },

      // 按fraud字段分组并统计数量
      {
        $group: {
          _id: "$fraud",
          count: { $sum: 1 },
        },
      },
    ];

    const results = await Rb.aggregate(pipeline);

    // 4. 处理聚合结果，提取诈骗和非诈骗数量
    let fraudCount = 0;
    let normalCount = 0;

    results.forEach((item) => {
      if (item._id === 1) {
        fraudCount = item.count;
      } else if (item._id === 0) {
        normalCount = item.count;
      }
    });

    ctx.body = util.success(
      {
        fraudCount,
        normalCount,
      },
      "获取最近上传批次的诈骗统计数据成功"
    );
  } catch (error) {
    ctx.body = util.fail(error.stack, "获取统计数据失败");
  }
});

module.exports = router;
